package com.hedl.practice.diyJava.io.study_inputstream.test;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class Main {
    public static void main(String[] args) throws IOException {
        InputStream input = null;

       /* try {
            input = new FileInputStream("/Users/a101/idea/人应该懂得放弃.txt");
            int n;
            while ((n = input.read()) != -1){
                System.out.println(n);
            }
        }finally {
            if (input != null){
                input.close();
            }
        }*/

        /**
         * 实际上，编译器并不会特别地为InputStream加上自动关闭。
         * 编译器只看try(resource = ...)中的对象是否实现了java.lang.AutoCloseable接口，
         * 如果实现了，就自动加上finally语句并调用close()方法。
         * InputStream和OutputStream都实现了这个接口，因此，都可以用在try(resource)中。
         */
        //使用try(resource)语法，让编译器自动为我们关闭资源，与上述代码少了input.close()
        try(InputStream inputStream = new FileInputStream("/Users/a101/idea/人应该懂得放弃.txt")){
            int n;
            while((n = inputStream.read()) != -1){
                System.out.println(n);
            }
        }   //// 编译器在此自动为我们写入finally并调用close()


        System.out.println("====================================缓冲===================================");
        /**
         * 学习缓冲原理的实现
         */

        try(InputStream inputStream = new FileInputStream("/Users/a101/idea/人应该懂得放弃.txt")){
            // 定义1000个字节大小的缓冲区:
            byte[] buffer = new byte[1000];
            int n;
            while((n = inputStream.read(buffer)) != -1){    //读取到缓冲区
                System.out.println("read " + n + " bytes.");
            }
        }

        System.out.println("====================================InputStream实现类===================================");
        /**
         * ByteArrayInputStream可以在内存中模拟一个InputStream：
         */
        byte[] data = {72,101,108,108,111,33};
        try(InputStream inputStream = new ByteArrayInputStream(data)){
            int n;
            while((n = inputStream.read()) != -1){
                System.out.print((char)n);        //转换成字节，会找ascll码72=H;101=e;108=l;111=o;33=!  Hello!
            }
        }

        System.out.println("==========================================================================");

        /**
         * 我们想从文件中读取所有字节，并转换成char然后拼成一个字符串，可以这么写：
         */
        String s;
        try(InputStream inputStream = new FileInputStream("/Users/a101/idea/人应该懂得放弃.txt")){
            int n;
            StringBuilder sb = new StringBuilder();
            while((n = inputStream.read()) != -1){
                sb.append((char) n);
            }
            s = sb.toString();
        }
        System.out.println(s);

        System.out.println("==========================================================================");

        /**
         * 把代码稍微改造一下，提取一个readAsString()的方法
         * 英文单词是不会产生乱码的，只有字符串会产生乱码；但是我们有专门的类和方法去处理乱码，后面章节讲解
         */
        String a;
        try(InputStream inputStream = new FileInputStream("/Users/a101/idea/book.txt")){
            a = readAsString(inputStream);
        }
        System.out.println(a);

        //在测试
        byte[] data1 = {72,101,108,108,111,33};
        try(InputStream inputStream = new ByteArrayInputStream(data1)){
            String s1 = readAsString(inputStream);
            System.out.println(s1);
        }

    }

    private static String readAsString(InputStream inputStream) throws IOException {
        int n;
        StringBuilder sb = new StringBuilder();
        while((n = inputStream.read()) != -1){
            sb.append((char) n);
        }
        return sb.toString();
    }
}
